﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using System.Collections.ObjectModel;
using Douban.Modules.Conversation.ViewModels;
using Douban.Modules.Conversation.Views;
using Douban.Core;
using Douban.Core.Events;
using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Unity;
using System.Windows.Threading;
using Douban.Api.Mail;
using Douban.Api;
using Douban.Modules.Conversation.Models;

namespace Douban.Modules.Conversation
{
    public class ConversationManager
    {
        private const double RefreshInterval = 60.0;
        private readonly IUnityContainer _container;
        private readonly IEventAggregator _eventAggregator;
        private readonly DoubanService _doubanService;
        private DispatcherTimer _receiveMessageReminder;
        private Dictionary<string, IConversationShellViewModel> _conversations;

        public ConversationManager(IUnityContainer container, IEventAggregator eventAggregator, DoubanService doubanService)
        {
            _container = container;
            _eventAggregator = eventAggregator;
            _eventAggregator.GetEvent<ContactDoubleClickedEvent>().Subscribe(CreateConversationViewModel);
            _eventAggregator.GetEvent<ReadMessageEvent>().Subscribe(CreateConversationViewModel);
            _doubanService = doubanService;
            _conversations = new Dictionary<string, IConversationShellViewModel>();
            InitializeReceiveMessageReminder();
            GetUnreadMessageFromInbox();
        }

        private void InitializeReceiveMessageReminder()
        {
            _receiveMessageReminder = new DispatcherTimer();
            _receiveMessageReminder.Interval = TimeSpan.FromSeconds(RefreshInterval);
            _receiveMessageReminder.Tick += Timer_Tick;
            _receiveMessageReminder.Start();
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            GetUnreadMessageFromInbox();
        }

        private void GetUnreadMessageFromInbox()
        {
            Mailbox Inbox = _doubanService.MailService.GetMailbox(MailboxType.Inbox, true);

            if (Inbox.Messages == null) return;

            foreach (var message in Inbox.Messages)
            {
                if (!_conversations.ContainsKey(message.Sender.Id))
                {
                    _eventAggregator.GetEvent<MessageArrivedEvent>().Publish(message);
                }
            }
        }

        private void CreateConversationViewModel(string contactId)
        {
            foreach (var conversation in _conversations)
            {
                if (conversation.Key == contactId)
                {
                    conversation.Value.View.RecoverView();
                    return;
                }
            }

            AddNewConversationToConversationDictionary(contactId);
        }

        private void CreateConversationViewModel(Message message)
        {
            string contactId = message.Sender.Id;
            AddNewConversationToConversationDictionary(contactId);

            IConversationShellViewModel conversationShellViewModel;
            _conversations.TryGetValue(contactId, out conversationShellViewModel);

            MessageModel messageModel = new MessageModel();
            messageModel.UserId = contactId;
            messageModel.Title = message.Title;
            messageModel.Content = _doubanService.MailService.GetMail(message.Id).Content;
            messageModel.IconUri = message.Sender.IconUri;

            IConversationWorkSpaceViewModel conversationWorkSpaceViewModel = conversationShellViewModel.ConversationWorkSpaceViewModel;

            conversationWorkSpaceViewModel.Messages.Add(messageModel);

            IChatLogViewModel chatLogViewModel = conversationWorkSpaceViewModel.ChatLogViewModel;

            chatLogViewModel.TodayMessages.Add(messageModel);

            chatLogViewModel.FileManager.StoreChatLog(chatLogViewModel.TodayMessages.ToArray(), DateTime.Now.ToString("yyyy-MM-dd"));
        }

        private void AddNewConversationToConversationDictionary(string contactId)
        {
            IConversationShellViewModel conversationViewModel = _container.Resolve<IConversationShellViewModel>();
            conversationViewModel.ContactId = contactId;
            conversationViewModel.Run();
            conversationViewModel.RemoveConversationFromCollection += RemoveConversationFromCollection;

            _conversations.Add(contactId, conversationViewModel);
        }

        private void RemoveConversationFromCollection(object sender, RemoveEventArgs e)
        {
            foreach (var conversation in _conversations)
            {
                if (conversation.Key == e.ContactId)
                {
                    _conversations.Remove(e.ContactId);
                    return;
                }
            }
        }
    }
}
